import Validate from './validate.js';
import $store from "@/store/index.js"
import $api from "api/index.js"
import $util from './index.js';
import permision from '@/utils/permission.js'
import siteInfo from '@/siteinfo.js';
// #ifdef H5
import $jweixin from "@/utils/jweixin.js"
// #endif
const PI = 3.1415926535897932384626;
const a = 6378245.0; // 长半轴
const ee = 0.00669342162296594323; // 扁率
export default {
	Validate,
	log: console.log,
	// log: () => {},
	wgs84togcj02(lng, lat) {
		let is_out = this.outOfChina(lng, lat)
		if (is_out) {
			return {
				lng,
				lat
			}
		} else {
			let dlat = this.transformlat(lng - 105.0, lat - 35.0);
			let dlng = this.transformlng(lng - 105.0, lat - 35.0);
			let radlat = lat / 180.0 * PI;
			let magic = Math.sin(radlat);
			magic = 1 - ee * magic * magic;
			let sqrtmagic = Math.sqrt(magic);
			dlat = (dlat * 180.0) / ((a * (1 - ee)) / (magic * sqrtmagic) * PI);
			dlng = (dlng * 180.0) / (a / sqrtmagic * Math.cos(radlat) * PI);
			let mglat = lat + dlat;
			let mglng = lng + dlng;
			return {
				lng: mglng,
				lat: mglat
			}
		}
	},
	/**
	 * 判断是否在国内，不在国内则不做偏移
	 * @param lng
	 * @param lat
	 * @returns {boolean}
	 */
	outOfChina(lng, lat) {
		lat = +lat
		lng = +lng
		// return !(lng > 73.66 && lng < 135.05 && lat > 3.86 && lat < 53.55)
		return (lng < 72.004 || lng > 137.8347) || ((lat < 0.8293 || lat > 55.8271) || false);
	},
	transformlat(lng, lat) {
		lat = +lat
		lng = +lng
		let ret = -100.0 + 2.0 * lng + 3.0 * lat + 0.2 * lat * lat + 0.1 * lng * lat + 0.2 * Math.sqrt(Math.abs(lng));
		ret += (20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0 / 3.0;
		ret += (20.0 * Math.sin(lat * PI) + 40.0 * Math.sin(lat / 3.0 * PI)) * 2.0 / 3.0;
		ret += (160.0 * Math.sin(lat / 12.0 * PI) + 320 * Math.sin(lat * PI / 30.0)) * 2.0 / 3.0;
		return ret
	},
	transformlng(lng, lat) {
		lat = +lat
		lng = +lng
		let ret = 300.0 + lng + 2.0 * lat + 0.1 * lng * lng + 0.1 * lng * lat + 0.1 * Math.sqrt(Math.abs(lng));
		ret += (20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0 / 3.0;
		ret += (20.0 * Math.sin(lng * PI) + 40.0 * Math.sin(lng / 3.0 * PI)) * 2.0 / 3.0;
		ret += (150.0 * Math.sin(lng / 12.0 * PI) + 300.0 * Math.sin(lng / 30.0 * PI)) * 2.0 / 3.0;
		return ret
	},
	// 计算直线距离
	getDistance(lat1, lon1, lat2, lon2) {
		const R = 6371e3; // 地球半径，单位米
		const phi1 = lat1 * Math.PI / 180; // 纬度1，弧度制
		const phi2 = lat2 * Math.PI / 180; // 纬度2，弧度制
		const phiDelta = (lat2 - lat1) * Math.PI / 180; // 两点纬度差，弧度制
		const lambdaDelta = (lon2 - lon1) * Math.PI / 180; // 两点经度差，弧度制

		const a = Math.sin(phiDelta / 2) * Math.sin(phiDelta / 2) +
			Math.cos(phi1) * Math.cos(phi2) *
			Math.sin(lambdaDelta / 2) * Math.sin(lambdaDelta / 2)
		const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a))

		const distance = R * c
		return distance
	},
	//格式化时间
	formatTime(date, format) {
		let newFormat = format || 'YY-M-D h:m:s';
		let formatNumber = this.formatNumber;
		let newDate = date || new Date();
		if (Object.prototype.toString.call(newDate).slice(8, -1) !== "Date") {
			newDate = new Date(date);
		}
		let week = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', '日', '一', '二', '三',
			'四',
			'五', '六'
		];
		return newFormat.replace(/YY|Y|M|D|h|m|s|week|周|星期/g, function(a) {
			switch (a) {
				case 'YY':
					return newDate.getFullYear();
				case 'Y':
					return (newDate.getFullYear() + '').slice(2);
				case 'M':
					return formatNumber(newDate.getMonth() + 1);
				case 'D':
					return formatNumber(newDate.getDate());
				case 'h':
					return formatNumber(newDate.getHours());
				case 'm':
					return formatNumber(newDate.getMinutes());
				case 's':
					return formatNumber(newDate.getSeconds());
				case '周':
					return "周" + week[newDate.getDay() + 7];
				case '星期':
					return "星期" + week[newDate.getDay() + 7];
				case 'week':
					return week[newDate.getDay()];
			}
		})
	},
	// 日期转时间戳
	DateToUnix: function(string) {
		var f = string.split(' ', 2);
		var d = (f[0] ? f[0] : '').split('-', 3);
		var t = (f[1] ? f[1] : '').split(':', 3);
		return (new Date(
			parseInt(d[0], 10) || null,
			(parseInt(d[1], 10) || 1) - 1,
			parseInt(d[2], 10) || null,
			parseInt(t[0], 10) || null,
			parseInt(t[1], 10) || null,
			parseInt(t[2], 10) || null
		)).getTime() / 1000;
	},
	//格式化数字
	formatNumber(n) {
		n = n.toString();
		return n[1] ? n : '0' + n
	},
	// 保留小数 （不四舍五入）
	formatDecimal(num, decimal) {
		num = num.toString()
		let index = num.indexOf('.')
		if (index !== -1) {
			num = num.substring(0, decimal + index + 1)
		} else {
			num = num.substring(0)
		}
		return parseFloat(num).toFixed(decimal)
	},
	formatDecimalText(value) {
		if (!value) return '0'
		const num = parseFloat(value)
		if (isNaN(num)) return '0'
		let val = num.toFixed(2)
		let text = (Number(val.replace(/(\d)(?=(\d{3})+\.)/g, '$1,')).toString()).replace(/\.00$/, '')
		return text
	},
	// 实时检测输入金额
	formatMoney(val) {
		if (val.slice(0, 1) == "0" && val.slice(1, 2) > 0) {
			val = val.slice(1, 2);
		}
		if (val.slice(0, 1) == ".") {
			val = '0.';
		}
		if (val == "0.00") {
			val = '0.0';
		}
		return val.replace(/[^\d\.]|^\./g, '').replace(/\.{2}/g, '.').replace(
			/^([1-9]\d*|0)(\.\d{1,2})(\.|\d{1})?$/, '$1$2').replace(/^0\d{1}/g, '0')
	},
	toWeiXinString(date) {
		let str;
		let newDate = date || new Date();
		if (Object.prototype.toString.call(newDate).slice(8, -1) !== "Date") {
			newDate = new Date(date);
		}
		const now = newDate;
		const today = new Date(now.getFullYear(), now.getMonth(), now.getDate());
		const yesterday = new Date(now.getFullYear(), now.getMonth(), now.getDate() - 1);
		const beforeYesterday = new Date(now.getFullYear(), now.getMonth(), now.getDate() - 2);
		const monday = new Date(today);
		monday.setDate(today.getDate() - (today.getDay() ? today.getDay() - 1 : 6));
		//注意：date初始化默认是按本地时间初始的，但打印默认却是按GMT时间打印的，也就是说打印出的不是本地现在的时间
		//LocaleString的打印也有点问题，"0点"会被打印为"上午12点"
		if (now.getTime() > today.getTime()) {
			str = "";
		} else if (now.getTime() > yesterday.getTime()) {
			str = "昨天";
		} else if (now.getTime() > beforeYesterday.getTime()) {
			str = "前天";
		} else if (now.getTime() > monday.getTime()) {
			const week = {
				"0": "周日",
				"1": "周一",
				"2": "周二",
				"3": "周三",
				"4": "周四",
				"5": "周五",
				"6": "周六"
			};
			str = week[now.getDay() + ""];
		} else {
			const hour = ["凌晨", "早上", "下午", "晚上"];
			const h = now.getHours();
			if (h == 12) str = "中午";
			else str = hour[parseInt(h / 6)];
			str = now.format("MM月dd ") + str;
		}
		str += now.format("HH:ss");
		return str;
	},
	//返回类型
	typeOf(param) {
		return Object.prototype.toString.call(param).slice(8, -1)
	},
	//判断是否为空
	isEmpty(param) {
		//基本类型为空
		let condition1 = param === '' || param === null || param === undefined || param === "NaN";
		let condition2;
		let condition3
		//引用类型为空
		if (!condition1) {
			condition2 = this.typeOf(param) === "Object" && Object.keys(param).length < 1;
			condition3 = this.typeOf(param) === "Array" && param.length < 1;
		}
		return condition1 || condition2 || condition3;
	},
	showLoading({
		title = "加载中",
		mask = true
	} = {}) {
		uni.showLoading({
			title,
			mask
		});
	},
	showToast({
		title,
		icon = "none"
	} = {}) {
		uni.showToast({
			title,
			icon,
			duration: 2000
		});
	},
	hideAll() {
		uni.hideLoading();
		uni.stopPullDownRefresh();
		uni.hideNavigationBarLoading();
	},
	showModal({
		title = "提示",
		content = "没有返回值,检查服务器是否正常"
	}) {
		uni.showModal({
			title,
			content,
			showCancel: false
		});
	},
	setNavigationBarColor({
		color = '#ffffff',
		bg
	}) {
		uni.setNavigationBarColor({
			frontColor: color,
			backgroundColor: bg,
			// animation: {
			// 	duration: 100,
			// 	timingFunc: 'easeIn'
			// }
		})
	},
	getQueryString(name) {
		let reg = new RegExp("([^?&]*)" + name + "=([^&]*)(&|$)")
		let r = window.location.href.match(reg)
		if (r !== null) return unescape(r[2])
		return ''
	},
	getHostname(url) {
		var reg = /^http(s)?:\/\/(.*?)\//
		// 必须是http开头或者https开头，结尾为'/'
		var ToReplace = 'Host/'
		url.replace(reg, ToReplace)
		url = reg.exec(url)[2];
		return url;
	},
	//获取标签上data
	getDataSet(e) {
		return e.currentTarget.dataset
	},
	//获表单控件值
	getValue(e) {
		return e.detail.value
	},
	pick(obj, arr) {
		return arr.reduce((acc, curr) => (curr in obj && (acc[curr] = obj[curr]), acc), {});
	},
	getUrlToStr(url, params) {
		console.log(url, params, "=====url, params")
		let text = url
		if (params) {
			text = `${url}?` + Object.keys(params)
				// .filter(key => params[key] || params[key] === 0)
				.filter(key => params[key]) // 删除无值的字段，可根据需要进行保留或删除
				.map(key => `${key}=${params[key]}`)
				.toString().replace(/,/g, '&')
		}
		return text
	},
	// 根据生日的月份和日期，计算星座。
	getAstro(month, day) {
		var s = '摩羯水瓶双鱼白羊金牛双子巨蟹狮子处女天秤天蝎射手摩羯'
		var arr = [20, 19, 21, 20, 21, 22, 23, 23, 23, 24, 23, 22]
		return s.substr(month * 2 - (day < arr[month - 1] ? 2 : 0), 2) + '座'
	},
	// 颜色转换
	rgbColor(color, rgb = 0.8) {
		const binaryPattern = /^#([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/i;
		const match = color.match(binaryPattern);
		if (match) {
			// 将二进制转换为十进制
			const r = parseInt(match[1], 16);
			const g = parseInt(match[2], 16);
			const b = parseInt(match[3], 16);
			return `rgba(${r}, ${g}, ${b}, ${rgb})`;
		}
		return color
	},
	goMap(item) {
		const _this = this
		let {
			lat,
			lng,
			address
		} = item
		if (!lat || !lng || !address) return
		// 判断系统安装的地图应用有哪些, 并生成菜单按钮
		let _mapName = [{
				title: `高德地图`,
				name: 'amap',
				androidName: 'com.autonavi.minimap',
				iosName: 'iosamap://'
			},
			{
				title: `腾讯地图`,
				name: 'qqmap',
				androidName: 'com.tencent.map',
				iosName: 'qqmap://'
			},
			{
				title: `百度地图`,
				name: 'baidumap',
				androidName: 'com.baidu.BaiduMap',
				iosName: 'baidumap://'
			},
			{
				title: `谷歌地图`,
				name: 'googlemap',
				androidName: 'com.google.android.apps.maps',
				iosName: 'comgooglemaps://'
			},
			{
				title: `Apple Maps`,
				name: 'applemap',
				androidName: 'com.apple.Maps',
				iosName: 'maps://'
			},
		]
		// 根据真机安装的地图软件 生成操作菜单
		let buttons = []
		let platform = uni.getSystemInfoSync().platform
		platform === 'android' && _mapName.forEach(item => {
			if (plus.runtime.isApplicationExist({
					pname: item.androidName
				})) {
				buttons.push(item)
			}
		})
		platform === 'ios' && _mapName.forEach(item => {
			if (plus.runtime.isApplicationExist({
					action: item.iosName
				})) {
				buttons.push(item)
			}
		})
		if (buttons.length) {
			plus.nativeUI.actionSheet({ //选择菜单
				title: `选择地图应用便于您查看导航`,
				cancel: `取消`,
				buttons: buttons
			}, function(e) {
				let _map = buttons[e.index - 1]
				_this.openURL(_map, platform, item)
			})
		} else {
			uni.showToast({
				title: '请安装高德/腾讯/百度/谷歌地图软件后再查看导航',
				icon: 'none'
			})
			return
		}
	},
	openURL(map, platform, item) {
		let {
			lat,
			lng,
			address,
			address_info = '',
			referer = '腾讯地图'
		} = item
		let _defaultUrl = {
			android: {
				"amap": `amapuri://route/plan/?sid=&did=&dlat=${lat}&dlon=${lng}&dname=${address}&dev=0&t=0`,
				'qqmap': `qqmap://map/geocoder?coord=${lat},${lng}&title${address_info}&addr=${address}=&referer=${referer}"`,
				'baidumap': `baidumap://map/direction?origin=${lat},${lng}&destination=name:${address}|latlng:${lat},${lng}&coord_type=wgs84&mode=driving&src=andr.baidu.openAPIdemo"`,
				'googlemap': `geo: + ${lat} + ',' + ${lng} + '?q=' + encodeURIComponent(${address})`
			},
			ios: {
				"amap": `iosamap://path?sourceApplication=fuxishan_uni_client&dlat=${lat}&dlon=${lng}&dname=${address}&dev=0&t=0`,
				'qqmap': `qqmap://map/geocoder?coord=${lat},${lng}&title${address_info}&addr=${address}=&referer=${referer}`,
				'baidumap': `baidumap://map/direction?origin=${lat},${lng}&destination=name:${address}|latlng:${lat},${lng}&mode=driving&src=ios.baidu.openAPIdemo`,
				'googlemap': `comgooglemaps://?q=${address}`,
				'applemap': `maps://?q=${address}&sll=${lat}+ ',' + ${lng}&z=10&t=s`
			}
		}
		let newurl = encodeURI(_defaultUrl[platform][map.name]);
		plus.runtime.openURL(newurl, function(res) {
			uni.showModal({
				content: res.message
			})
		}, map.androidName ? map.androidName : '');
	},
	async toAsyAccLogin() {
		let userInfo = uni.getStorageSync("userInfo")
		let {
			account_login = 0
		} = userInfo && userInfo.id ? userInfo : {
			account_login: 0
		}
		if (account_login) {
			$store.commit('updateUserItem', {
				key: 'autograph',
				val: ''
			})
			$store.commit('updateUserItem', {
				key: 'userInfo',
				val: {}
			})
			$store.commit('updateUserItem', {
				key: 'userCoachStatus',
				val: {}
			})
		}
	},
	async toAsyncLogin() {
		let pageArr = ['pages/order', 'user/pages/coupon/get-info']
		let redirectPageArr = [`dynamic/pages/detail`, `user/pages/stored/list`, `memberdiscount/pages/index`]
		let pages = getCurrentPages()
		let {
			route,
			options = {},
			data = {
				options: {}
			}
		} = pages[pages.length - 1]
		// #ifdef MP-WEIXIN
		options = data.options
		// #endif
		options.islogin = 1

		// console.log(route, "=====route")
		let port = 1
		if ((route.includes('technician/pages') && route != 'technician/pages/apply') || [
				'pages/coach-index'
			].includes(route)) {
			port = 2
		}
		if ((route.includes('agent/pages') && route != 'agent/pages/apply') || [
				'pages/agent-index'
			].includes(route)) {
			port = 3
		}
		let loginUrl = [``, `pages/login`, `technician/pages/login`, `agent/pages/login`][port]
		let initUrl = [``, `pages/service`, `pages/coach-index`, `pages/agent-index`][port]

		route = route === loginUrl ? initUrl : route
		let loginPage = await this.getUrlToStr(`/${route}`, options)
		// console.log(port, loginPage, "====port , loginPage")

		let openType = pageArr.includes(route) || port != 1 ? `reLaunch` : redirectPageArr.includes(route) ?
			`redirectTo` : `navigateTo`
		$store.commit('updateUserItem', {
			key: 'loginPage',
			val: loginPage
		})
		this.goUrl({
			url: `/${loginUrl}`,
			openType
		})
	},
	toCheckLogin(param) {
		let {
			loginType = 'weixin',
				userInfo
		} = $store.state.user

		// #ifdef H5
		loginType = 'weixin'
		// #endif

		let {
			id: uid = 0,
			phone = ''
		} = userInfo
		let {
			force_login,
			short_code_status = 0,
			bind_phone_type = 0
		} = $store.state.config.configInfo

		let checkLogin = true
		if (!uid || (force_login == 1 && short_code_status && bind_phone_type && !phone)) {
			checkLogin = false
			let pages = getCurrentPages()
			let {
				route,
				options = {}
			} = pages[pages.length - 1]
			let routeUrl = this.getUrlToStr(`/${route}`, options)
			let url = !uid ? `/pages/login` : `/user/pages/phone`
			$store.commit('updateUserItem', {
				key: 'loginPage',
				val: routeUrl
			})
			this.goUrl({
				url
			})
		}
		if (checkLogin) {
			this.goUrl(param)
		}
	},
	async toCheck() {
		let check = true
		let {
			id: uid = 0,
			phone
		} = $store.state.user.userInfo
		let {
			force_login,
			attendant_name,
			short_code_status
		} = $store.state.config.configInfo
		if (force_login == 1 && !uid) {
			let [res_del, {
				confirm
			}] = await uni.showModal({
				content: `马上注册查看更多${attendant_name}信息`,
				// #ifdef H5
				showCancel: false,
				// #endif
				confirmText: `去注册`
			})
			check = false
			if (!confirm) return
			let pages = getCurrentPages()
			let {
				route,
				options = {}
			} = pages[pages.length - 1]
			let loginPage = this.getUrlToStr(`/${route}`, options)
			$store.commit('updateUserItem', {
				key: 'loginPage',
				val: loginPage
			})
			this.goUrl({
				url: `/pages/login`
			})
		}
		return check
	},
	// type 1用户；2技-师
	toLoginOut(type = 1) {
		console.log(type, "====toLoginOut")
		let arr = ['autograph', 'userInfo', 'userCoachStatus', 'city_info', 'location', 'changeAddr', 'appLogin',
			'loginType', 'loginPage', 'isGzhLogin', 'isShowLogin', 'mineInfo', 'coachInfo', 'agentInfo',
			'scanRecordId', 'is_register', 'agentportType'
		]
		arr.map(key => {
			$store.commit('updateUserItem', {
				key,
				val: key === 'isShowLogin' ? true : key === 'isGzhLogin' ? false : ['coachInfo',
					'agentInfo'
				].includes(key) ? {
					id: -1,
				} : ['userInfo', 'location', 'userCoachStatus'].includes(key) ? {} : ''
			})
		})

		let methodArr = ['updateServiceItem', 'updateTechnicianItem', 'updateMapItem', 'updateDynamicItem',
			'updateOrderItem'
		]
		methodArr.map(item => {
			$store.commit(item, {
				key: 'pageActive',
				val: false
			})
		})

		$store.commit('updateOrderItem', {
			key: 'order_unix_list',
			val: []
		})
		$store.commit('updateUserItem', {
			key: 'noChangeLoca',
			val: {
				noloca: false
			}
		})
		$util.showToast({
			title: `退出登录`
		})
		setTimeout(() => {
			let {
				is_app_user
			} = $store.state.config.configInfo
			let page = [``, `/pages/service`, `/technician/pages/login`, `/agent/pages/login`][type]
			let port = ''
			// #ifdef MP-WEIXIN-COACH || H5-COACH
			port = 'coach/'
			// #endif
			// #ifdef MP-WEIXIN-AGENT || H5-AGENT
			port = 'agent/'
			// #endif
			// #ifdef APP-PLUS
			port = ['', '', 'coach/', 'agent/'][is_app_user]
			// #endif
			// #ifdef H5
			let {
				siteroot
			} = siteInfo
			let url = siteroot.split('/index.php')[0]
			let {
				portName
			} = $store.state.user
			let href = `${url}/${port}${portName}/#${page}`
			window.location.href = href
			// #endif
			// #ifndef H5
			$util.goUrl({
				url: page,
				openType: `reLaunch`
			})
			// #endif
		}, 1000)
	},
	goUrl({
		url = "",
		openType = "navigateTo",
		path = "",
		query = ""
	} = {}) {
		let that = this;
		if (!url) return;
		if (this.typeOf(query) == 'Object') {
			let queryStr = Object.keys(query).map(k => `${k}=${query[k]}`).join('&');
			url = `${url}&${queryStr}`
		}
		let list = ["navigateTo", "redirectTo", "switchTab", "reLaunch"];
		if (list.includes(openType)) {
			if (openType == 'navigateTo' && getCurrentPages().length > 9) {
				uni.redirectTo({
					url
				})
			} else {
				uni[openType]({
					url
				})
			}
		}
		//返回
		openType == "navigateBack" && uni.navigateBack({
			delta: url
		})

		//跳转小程序
		if (openType == "miniProgram") {
			let mini_data = that.deepCopy(url)
			let arr = mini_data.split(";")
			// console.log(arr, "======= arr miniProgram")
			let appId = arr[0]
			let path = arr.length > 1 ? arr[1] : ''
			uni.navigateToMiniProgram({
				appId,
				path
			})
		}

		//打电话
		openType == "call" && uni.makePhoneCall({
			phoneNumber: url
		})
		// 复制文本
		openType == 'copy' && uni.setClipboardData({
			data: url,
			success: function(res) {
				uni.getClipboardData({
					success: function(res) {
						// #ifdef MP-BAIDU 
						that.showToast({
							title: '复制成功'
						})
						// #endif
						console.log('复制文本成功 ==>', res.data);
					}
				});
			}
		})
		//跳转网页/播放视频
		if (openType == "web" || openType == 'video') {
			let encode_url = encodeURIComponent(url)
			uni.navigateTo({
				url: `/user/pages/common/${openType}?url=${encode_url}`
			})
		}
	},
	// 刷新上页数据
	back() {
		let pages = getCurrentPages(); //当前页面栈
		if (pages.length > 1) {
			var beforePage = pages[pages.length - 2]; //获取上一个页面实例对象  
			//触发父页面中的方法change()
			beforePage.$vm.initRefresh()
		}
	},
	//获取页面对象，0时为当前页面
	getPage(index = 0) {
		let pages = getCurrentPages();
		let page = pages[pages.length - 1 + index]
		return page.$vm
	},
	// 预览图片
	previewImage(param) {
		let {
			current,
			urls
		} = param;
		uni.previewImage({
			current,
			urls,
		})
	},
	// 根据type获取数据字符串 
	getItems(o, type = 'id', sign = ',') {
		let items = [];
		o = o || [];
		o.forEach((item) => {
			items.push(item[type])
		})
		return items.join(sign);
	},
	// 检查授权
	async checkAuth({
		type = "userLocation",
		tip = "",
		checkApp = false
	} = {}) {
		// #ifdef MP-WEIXIN
		let contentList = {
			phone: "获取手机号",
			userLocation: "地理位置",
			userLocationBackground: "在使用期间和离开后",
			address: "通讯地址",
			invoiceTitle: "发票抬头",
			invoice: "获取发票",
			werun: "微信运动步数",
			record: "录音功能",
			writePhotosAlbum: "你的保存到相册功能",
			camera: "摄像头"
		}
		tip = tip || `您暂未开启您的${contentList[type]}的授权，是否开启?`
		// 声明
		let err, result;
		[err, result] = await uni.getSetting();
		//获取配置失败
		if (err) {
			return Promise.reject(err)
		}
		//如果已授权
		if (result.authSetting[`scope.${type}`]) {
			return true
		}
		// 调用获取权限
		[err, result] = await uni.authorize({
			scope: `scope.${type}`
		})
		//获取成功
		if (!err) {
			return true
		}
		uni.hideLoading()
		//提示去设置
		return new Promise((resove, reject) => {
			uni.showModal({
				title: `是否授权${contentList[type]}`,
				content: tip,
				success(res) {
					if (res.confirm) {
						uni.openSetting({
							success(result) {
								if (result.authSetting[
										`scope.${type}`]) {
									resove(true)
								} else {
									reject()
								}
							}
						})
					} else {
						reject()
					}
				}
			})
		})
		// #endif

		// #ifdef APP-PLUS
		if (!checkApp) return
		if (type !== 'userLocation') return
		await permision.gotoAppSetting()
		$store.commit('updateUserItem', {
			key: 'locaRefuse',
			val: false
		})
		// #endif
	},
	//深拷贝
	deepCopy(o) {
		let that = this;
		if (o instanceof Array) {
			var n = [];
			for (var i = 0; i < o.length; ++i) {
				n[i] = that.deepCopy(o[i]);
			}
			return n;
		} else if (o instanceof Function) {
			var n = new Function("return " + o.toString())();
			return n
		} else if (o instanceof Object) {
			var n = {}
			for (var i in o) {
				n[i] = that.deepCopy(o[i]);
			}
			return n;
		} else {
			return o;
		}
	},
	getOptions(options, comminOptions = {}) {
		return Object.assign({}, comminOptions, this.formatOptions(options))
	},
	// 微信支付
	async pay(pay_list, isPayFail = true) {
		let that = this;
		let param = {}
		// console.log(pay_list, isPayFail, "=====index pay-list")

		// #ifdef H5
		param = that.pick(pay_list, ['appId', 'timeStamp', 'nonceStr', 'package', 'signType', 'paySign'])
		if (typeof WeixinJSBridge != "undefined") {
			return new Promise((resove, reject) => {
				WeixinJSBridge.invoke(
					'getBrandWCPayRequest', param,
					function(res) {
						try {
							if (res.err_msg == "get_brand_wcpay_request:ok") {
								setTimeout(() => {
									resove(true)
								}, 1000)
							} else {
								that.showToast({
									title: `支付失败`
								})
								setTimeout(() => {
									reject("支付失败")
								}, 1000)
							}
						} catch (e) {
							uni.showModal({
								content: JSON.stringify(res)
							})
						}
					})
			});
		}
		// #endif


		let {
			provider = 'wxpay',
				orderInfo = ''
		} = pay_list

		// #ifdef MP-WEIXIN
		param = that.pick(pay_list, ['nonceStr', 'package', 'signType', 'paySign', 'timeStamp'])
		// #endif

		// #ifdef APP-PLUS
		if (provider == 'wxpay') {
			let {
				adapay = 0,
					type = 0,
					order_code: oid = ''
			} = pay_list
			if (adapay) {
				that.toAdapay({
					path: `/user/pages/adapay-pay?type=${type}&oid=${oid}`
					// type: 2 // 2体验版，默认0正式版 发版需注释
				})
				return 'adapay_app_wechat'
			}

			orderInfo = that.pick(pay_list, ['appid', 'noncestr', 'package', 'partnerid', 'prepayid', 'timestamp'])
			orderInfo.sign = pay_list.paySign
			orderInfo = JSON.stringify(orderInfo)
		}
		if (provider == 'alipay' && pay_list.orderInfo && typeof(pay_list.orderInfo) === 'object' && pay_list
			.orderInfo.expend) {
			let {
				pay_info
			} = pay_list.orderInfo.expend
			let {
				isIos
			} = $store.state.config.configInfo
			let aliKey = isIos ? 'alipay' : 'alipays'
			let qr = `${aliKey}://platformapi/startapp?saId=10000007&qrcode=${pay_info}`
			plus.runtime.openURL(qr, function(error) {
				console.log(error, "===error")
			})
			return 'adapay_app_alipay'
		}

		param = {
			provider,
			orderInfo
		}
		// #endif

		// #ifndef H5
		let [err, res] = await uni.requestPayment(param)
		if (err) {
			console.log("=======pay err", err, isPayFail)
			if (isPayFail) {
				that.showToast({
					title: `支付失败`
				})
			}
			await Promise.reject("支付失败")
		} else {
			return true
		}
		// #endif
	},
	async toAdapay(params) {
		let that = this
		let {
			wechat_original_id = ''
		} = await $api.base.separateConfigInfo()
		if (!wechat_original_id) {
			that.showToast({
				title: `暂未关联小程序，不支持微信支付哦！`
			})
			return
		}
		params.id = wechat_original_id
		plus.share.getServices(function(res) {
				let arr = res.filter(item => {
					return item.id == 'weixin'
				})
				var sweixin = arr && arr.length > 0 ? arr[0] : null
				if (sweixin) {
					// console.log(params, "====params")
					sweixin.launchMiniProgram(params)
				} else {
					that.showToast({
						title: '当前环境不支持微信操作!'
					})
				}
			},
			function(e) {
				console.log(JSON.stringify(e))
			})
	},
	// 检测定位权限
	async checkPermission() {
		let status = null
		if (plus.os.name == 'Android' && plus.navigator.checkPermission(
				'android.permission.ACCESS_FINE_LOCATION') ===
			'undetermined') {
			status = 0
		}
		if (permision.isIOS) {
			status = await permision.requestIOS('location')
		}
		// let status = permision.isIOS ? await permision.requestIOS('location') :
		// 	await permision.requestAndroid('android.permission.ACCESS_FINE_LOCATION');
		if (status === null || status === 1) {
			status = 1
		}
		return status
	},
	// 根据生日的月份和日期，计算星座。
	getAstro(month, day) {
		var s = '摩羯水瓶双鱼白羊金牛双子巨蟹狮子处女天秤天蝎射手摩羯'
		var arr = [20, 19, 21, 20, 21, 22, 23, 23, 23, 24, 23, 22]
		return s.substr(month * 2 - (day < arr[month - 1] ? 2 : 0), 2) + '座'
	},
	// 获取省市区
	async getCityAddr(address) {
		var reg = /.+?(省|市|自治区|自治州|县|区)/g;
		let isReg = address.includes('省') || address.includes('省') || address.includes('市') ||
			address.includes(
				'自治区') || address.includes('自治州') || address.includes('县') || address.includes(
				'区')
		let cityArr = isReg ? Array.from(address.match(reg)) : []
		if (cityArr && (cityArr.length == 1 || (cityArr.length > 0 && ['北京市', '天津市', '上海市',
				'重庆市', '香港特别行政区',
				'澳门特别行政区'
			].includes(cityArr[0])))) {
			cityArr.unshift(cityArr[0])
		}
		let len = cityArr.length
		let province = len > 0 ? cityArr[0] : ''
		let city = len > 1 ? cityArr[1] : ''
		let area = len > 2 ? cityArr[2] : ''
		let info = `${province}${city}${area}`
		return {
			len,
			province,
			city,
			area,
			info
		}
	},
	// 获取地址
	async getLocation() {
		let that = this
		let locationInfo = {
			lat: 0,
			lng: 0,
			address: '',
			province: '',
			city: '',
			district: ''
		}
		// #ifdef APP-PLUS
		let status = await that.checkPermission()
		if (status !== 1) {
			return locationInfo
		}
		// #endif
		$store.commit('updateUserItem', {
			key: 'isUtilLoca',
			val: true
		})
		let {
			isConsole = false
		} = $store.state.user
		return new Promise((resove, reject) => {
			try {
				let isNotGet = true
				let isTimeOut = false
				let timeUnix = 4000
				// #ifdef APP-PLUS
				timeUnix = 7000
				// #endif
				setTimeout(() => {
					if (isConsole) {
						that.showToast({
							title: `${timeUnix} - ms秒后 isNotGetLoca-${isNotGet}`
						})
					}
					if (isNotGet) {
						isTimeOut = true
						$store.commit('updateUserItem', {
							key: 'isUtilLoca',
							val: false
						})
						// #ifdef APP-PLUS
						$store.commit('updateUserItem', {
							key: 'appCheckLocaStatus',
							val: 0
						})
						// #endif
						resove(locationInfo)
					}
				}, timeUnix)
				uni.getLocation({
					// #ifdef H5
					type: 'wgs84',
					// #endif
					// #ifndef H5
					type: 'gcj02',
					// #endif
					success: function(res) {
						if (!isTimeOut) {
							// #ifdef H5
							let {
								latitude,
								longitude
							} = res
							let {
								lat,
								lng
							} = that.wgs84togcj02(longitude, latitude)
							if (isConsole) {
								that.showToast({
									title: typeof(lat)
								})
							}
							lat = "" + parseFloat(lat).toFixed(6)
							lng = "" + parseFloat(lng).toFixed(6)
							// #endif
							// #ifndef H5
							let {
								latitude: lat,
								longitude: lng
							} = res
							// #endif
							locationInfo = Object.assign({}, locationInfo, {
								lat,
								lng
							})
							// if (isConsole) {
							// 	that.showModal({
							// 		content: '=getlocation-success-locationInfo=' + JSON
							// 			.stringify(locationInfo)
							// 	})
							// }
							resove(locationInfo)
						}
					},
					complete: function(e) {
						isNotGet = false
						if (isConsole) {
							that.showModal({
								content: '=getlocation=' + JSON
									.stringify(e)
							})
						}
						$store.commit('updateUserItem', {
							key: 'isUtilLoca',
							val: false
						})
						// #ifdef APP-PLUS
						$store.commit('updateUserItem', {
							key: 'appCheckLocaStatus',
							val: 0
						})
						// #endif
					},
					fail: function(e) {
						if (!isTimeOut) {
							// #ifdef H5
							$jweixin.getWxLocation().then(res => {
								console.log(
									'===jweixin.getWxLocation===',
									res)
								if (isConsole) {
									that.showModal({
										content: '=jweixin.getWxLocation=' +
											JSON.stringify(res)
									})
								}
								let {
									latitude: lat,
									longitude: lng
								} = res
								locationInfo = Object.assign({},
									locationInfo, {
										lat,
										lng
									})
								if (!isTimeOut) {
									resove(locationInfo)
								}
							})
							// #endif
							// #ifndef H5
							resove(locationInfo)
							// #endif
						}
					}
				})
			} catch (e) {
				$store.commit('updateUserItem', {
					key: 'isUtilLoca',
					val: false
				})
				// #ifdef APP-PLUS
				$store.commit('updateUserItem', {
					key: 'appCheckLocaStatus',
					val: 0
				})
				// #endif
				resove(locationInfo)
			}
		})
	},
	// 选择地址
	async chooseLocation(type = 0) {
		let param = {}
		// #ifdef MP-WEIXIN
		await this.checkAuth({
			type: 'userLocation'
		})
		// #endif

		// #ifndef MP-WEIXIN
		let {
			lat: latitude,
			lng: longitude
		} = await this.getLocation()

		if ($store.state.user.isConsole) {
			this.showToast({
				title: `chooseLoca-${latitude}-${longitude}`
			})
		}

		if (!latitude && !longitude) {
			let {
				lat: ipLat,
				lng: ipLng
			} = await this.getAddressByIp()
			if (!ipLat && !ipLng) {
				let {
					lat: locaLat = 0,
					lng: locaLng = 0
				} = $store.state.user.location
				ipLat = locaLat
				ipLng = locaLng
			}
			latitude = ipLat
			longitude = ipLng
		}

		param = {
			latitude,
			longitude
		}
		// #endif

		let [err, loca_data] = await uni.chooseLocation(param)
		let {
			name = '',
				address = '',
				latitude: lat = '',
				longitude: lng = ''
		} = err ? {
			name: '',
			address: '',
			latitude: '',
			longitude: ''
		} : loca_data
		if (type == 1) {
			address = address || name
		}
		if (type == 2) {
			address = address ? `${address} ${name}` : name
		}
		let loca_params = type == 1 ? {
			lat,
			lng,
			name,
			address,
			province: '',
			city: '',
			district: ''
		} : {
			lat,
			lng,
			name,
			address
		}
		return loca_params
	},
	// 获取定位
	async getUtilLocation(updateLoca = true, islogin = false) {
		let locaParams = this.deepCopy($store.state.user.location)
		let {
			user_update_location = 0,
				app_model_type = 0
		} = $store.state.config.configInfo
		if (locaParams && locaParams.lat && (!user_update_location || islogin)) {
			locaParams = this.pick(locaParams, ['lat', 'lng'])
		}
		let {
			lat,
			lng
		} = await this.getLocation()
		if ($store.state.user.isConsole && lat && lng) {
			this.showToast({
				title: `getUtilLocation-${lat}-${lng}`
			})
		}
		let isIp = false
		let isIpLoca = false

		if (!lat && !lng) {
			// #ifdef APP-PLUS
			if (app_model_type == 1) {
				isIpLoca = true
			}
			// #endif
			// #ifndef APP-PLUS
			isIpLoca = true
			// #endif
		}
		if (isIpLoca) {
			let loca = await this.getAddressByIp()
			lat = loca.lat
			lng = loca.lng
			isIp = true
			if ($store.state.user.isConsole) {
				this.showToast({
					title: `getUtilLocation-IP-${lat}-${lng}`
				})
			}
		}

		$store.commit('updateUserItem', {
			key: 'auth_location',
			val: lat && lng ? true : false
		})
		let location = this.toChangeUpdateUtilLoca(updateLoca, locaParams, {
			isIp,
			lat,
			lng,
			is_util_loca: 1
		})
		return location
	},
	async getCoachUtilLoca(isUpdate = true, isAddr = false) {
		let lat = 0
		let lng = 0
		// #ifdef H5
		let {
			latitude,
			longitude
		} = await $jweixin.getWxLocation()
		lat = latitude
		lng = longitude
		// #endif
		// #ifndef H5
		let loca = await this.getLocation()
		lat = loca.lat
		lng = loca.lng
		// #endif
		if ($store.state.user.isConsole) {
			this.showToast({
				title: `getCoachUtilLoca-${lat}-${lng}`
			})
		}
		let isIp = false
		if (isUpdate) {
			let location = {
				isIp,
				lat,
				lng,
				address: ''
			}
			if (isAddr) {
				location = await this.getMapAddr({
					lat,
					lng
				})
			}
			this.updateCoachAddr(location)
		}
		return {
			lat,
			lng,
			isIp
		}
	},
	toChangeUpdateUtilLoca(updateLoca, loca, locaParams) {
		let datas = Object.assign({}, loca, locaParams)
		let {
			lat = 0,
				lng = 0
		} = datas
		if (updateLoca && lat && lng) {
			$store.commit('updateUserItem', {
				key: 'location',
				val: datas
			})
		}
		return datas
	},
	// 解析地址
	async getMapInfo(isIp = true, updateLoca = true, params = {}, changeAddr =
		false,
		isUpdate = false) {
		let {
			location = {}
		} = $store.state.user
		if (params.lat && params.lng) {
			location = params
		}
		let {
			lat,
			lng
		} = location
		let {
			realtime_location = 0,
				user_update_location = 0
		} = $store.state.config.configInfo

		let {
			status: coach_status = 0,
			coach_position = 0
		} = $store.state.user.userCoachStatus

		if (lat && lng) {
			if (user_update_location || isUpdate) {
				location = await this.getMapAddr({
					lat,
					lng
				})
				if (updateLoca) {
					$store.commit('updateUserItem', {
						key: 'location',
						val: location
					})
				}
				if (!isIp && coach_position && coach_status == 2 && ((
							realtime_location && !changeAddr) || params
						.lat)) {
					this.updateCoachAddr(location)
				}
			} else if (!isIp && coach_position && coach_status == 2) {
				this.updateCoachAddr({
					lat,
					lng,
					address: ''
				})
			}
		}
	},
	async getAddressByIp() {
		let data = await $api.base.getAddressByIp()
		let {
			status,
			result
		} = JSON.parse(data)
		if (status === 0 || status === 1) {
			if (status == 1) {
				result = {
					location: {
						lat: 0,
						lng: 0
					},
					ad_info: {
						province: '',
						city: '',
						district: ''
					}
				}
			}
			let {
				lat,
				lng
			} = result.location
			let {
				province,
				city,
				district
			} = result.ad_info
			let location = {
				lat,
				lng,
				address: '',
				province,
				city,
				district
			}
			return location
		}
	},
	async getMapAddr(location) {
		let {
			lat,
			lng
		} = location
		let data = await $api.base.getMapInfo({
			location: `${lat},${lng}`
		})
		if (lat && lng) {
			let {
				status,
				result
			} = JSON.parse(data)
			if (status == 0 || status == 1) {
				if (status == 1) {
					result = {
						address: '暂未解析到位置信息',
						address_component: {
							province: '',
							city: '',
							district: ''
						}
					}
				}
				let {
					address = '暂未解析到位置信息',
						address_component = {},
						formatted_addresses = {}
				} = result
				if (status == 0) {
					let {
						recommend = '',
							standard_address
					} = formatted_addresses
					address = `${standard_address} ${recommend}`
				}
				let {
					province,
					city,
					district
				} = address_component
				location = {
					lat,
					lng,
					address,
					province,
					city,
					district
				}
			}
		}
		return location
	},
	async updateCoachAddr(location) {
		let {
			lat = 0,
				lng = 0,
				isIp = false
		} = location
		if (lat && lng && !isIp) {
			let {
				userCoachStatus = {},
					coachInfo = {}
			} = $store.state.user
			let upParams = $util.pick(location, ['lat', 'lng',
				'address'
			])
			if (!upParams.address) {
				delete upParams.address
			}
			try {
				await $api.technician.coachUpdate(upParams)
				let address_update_time = $util.formatTime(new Date(Math
						.ceil(new Date().getTime())),
					'YY-M-D h:m:s')
				let val = Object.assign({}, $util.deepCopy(userCoachStatus), upParams)
				let cval = Object.assign({}, $util.deepCopy(coachInfo), upParams, {
					address_update_time
				})
				$store.commit('updateUserItem', {
					key: 'userCoachStatus',
					val
				})
				$store.commit('updateUserItem', {
					key: 'coachInfo',
					val: cval
				})
			} catch (e) {}
		}
	}
}